package atomic;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;

/**
 * @author <a href='https://gitee.com/hzf2281'>codefish</a>
 * @version 1.0.0
 * @since 2022/08/21 下午 02:05
 */
public class AtomicFiledUpdateTest {


    public static void main(String[] args) throws InterruptedException {
        BankCount bankCount = new BankCount();
        CountDownLatch latch = new CountDownLatch(50);

        for (int i = 0; i < 50; i++) {
            new Thread(() -> {
                try {
                    for (int j = 0; j < 1000; j++) {
                        bankCount.transfer();
                    }
                } finally {
                    latch.countDown();
                }

            }).start();
        }

        latch.await();
        //输出结果为50000
        System.out.println(bankCount.getMoney());
    }

    static class BankCount {
        final String bankName = "CCB";

        //需要进行原子操作的字段必须被声明为volatile
        private volatile int money = 0;
        //对象域的原子操作对象建议声明为final static，防止对象引用被修改，而且保证只有一个实例
        final static AtomicIntegerFieldUpdater<BankCount> fieldUpdater = AtomicIntegerFieldUpdater.newUpdater(BankCount.class, "money");

        //通过内置锁来实现互斥原子操作
//         public synchronized void transfer(){
//             money++;
//         }

        //使用AtomicIntegerFieldUpdater实现CAS原子操作
        public void transfer() {
            fieldUpdater.incrementAndGet(this);
        }

        public int getMoney() {
            return money;
        }

    }
}
